# Copyright 2018- The Pixie Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

load("@io_bazel_rules_docker//container:image.bzl", "container_image")
load("@io_bazel_rules_docker//java:image.bzl", "java_image")
load("@rules_java//java:defs.bzl", "java_binary")
load("//bazel:graal.bzl", "graal_native_binary")
load("//bazel:pl_build_system.bzl", "pl_cc_binary")
load("//bazel:toolchain_transitions.bzl", "java_graal_binary")
load("//src/stirling/source_connectors/perf_profiler/testing:testing.bzl", "jdk_names")

package(default_visibility = ["//src/stirling:__subpackages__"])

# When invoking "profiler_test_with_agent", to inject the JVMTI agent,
# we need a command line arg. that looks like this:
# -agentpath:/path/to/libagent.so=<symbolization-file-path-prefix>
# We build this up using so_path, symbol_file_path, and jvm_flags, below.

# Construct the agent path portion of the command line arg.
so_path = "-agentpath:$(location //src/stirling/source_connectors/perf_profiler/java/agent:agent)"

# The agent_test will be create the symbol in directory "java-agent-test-<PX_JVMTI_AGENT_HASH>"
# in the test cwd. The suffix "-<PX_JVMTI_AGENT_HASH>" is added by the agent itself.
symbol_file_path = "./java-agent-test"

# Construct the full cmd line args here.
jvm_flags = [so_path + "=" + symbol_file_path]

java_binary(
    name = "profiler_test_with_agent",
    srcs = ["ProfilerTest.java"],
    args = ["-XX:+PreserveFramePointer"],
    data = ["//src/stirling/source_connectors/perf_profiler/java/agent"],
    jvm_flags = jvm_flags,
    main_class = "ProfilerTest",
)

java_binary(
    name = "profiler_test",
    srcs = ["ProfilerTest.java"],
    args = ["-XX:+PreserveFramePointer"],
    main_class = "ProfilerTest",
)

pl_cc_binary(
    name = "java",
    srcs = ["fake_java.cc"],
    deps = [
        "//src/common/fs:cc_library",
        "//src/stirling/bpf_tools/bcc_bpf_intf:cc_library",
        "//src/stirling/source_connectors/perf_profiler/java:cc_library",
        "//src/stirling/source_connectors/perf_profiler/java/agent:cc_headers",
    ],
)

symlinks_by_jdk = {
    # The java_image declaration expects the java binary to be located at /usr/bin/java,
    # but, these docker base images have the java binary at a 'non-standard' location.
    # To fix this, we include a symlink parameter in the relevant container_image declarations.
    "adopt-j9": {"/usr/bin/java": "/opt/java/openjdk/bin/java"},
    "ibm": {"/usr/bin/java": "/opt/ibm/java/jre/bin/java"},
}

# jdk_bases and jdk_symlinks are used to create a container_image declaration for each of our jdks.
jdk_bases = ["@{jdk_name}//image".format(jdk_name = jdk_name) for jdk_name in jdk_names]

jdk_symlinks = [symlinks_by_jdk[jdk_name] if jdk_name in symlinks_by_jdk else {} for jdk_name in jdk_names]

# Declare one container_image for each jdk we are testing. We do this (vs. going directly to
# java_image) because some JDK base images will need a symlink for /path/to/java to /usr/bin/java.
[
    container_image(
        name = jdk_name,
        base = jdk_base,
        symlinks = jdk_symlinks,
    )
    for jdk_name, jdk_base, jdk_symlinks in zip(jdk_names, jdk_bases, jdk_symlinks)
]

# Declare one java_image per jdk. This will be the test image which includes our toy test app.
[
    java_image(
        name = jdk_name + "-java-profiler-test-image",
        srcs = ["ProfilerTest.java"],
        args = ["-XX:+PreserveFramePointer"],
        base = jdk_name,
        main_class = "ProfilerTest",
    )
    for jdk_name in jdk_names
]

java_graal_binary(
    name = "graal_java_profiler_test",
    srcs = ["ProfilerTest.java"],
    args = ["-XX:+PreserveFramePointer"],
    main_class = "ProfilerTest",
)

graal_native_binary(
    name = "graal_java_test_aot",
    extra_args = [
        "--no-fallback",
        "-H:Class=ProfilerTest",
        "-H:-DeleteLocalSymbols",
        "-H:+PreserveFramePointer",
        "-H:+ReportUnsupportedElementsAtRuntime",
    ],
    graal_runtime = "@remotejdk_openjdk_graal_17//:jdk",
    java_binary = ":graal_java_profiler_test",
    output_name = "ProfilerTest",
)

filegroup(
    name = "graal-vm-aot-test",
    srcs = [":graal_java_test_aot"],
)

java_image(
    name = "java_image_base-java-profiler-test-image-omit-frame-pointer",
    srcs = ["ProfilerTest.java"],
    base = "java_image_base",
    main_class = "ProfilerTest",
)
